package org.jeecg.modules.iot.jtt808.req;

import io.netty.buffer.ByteBuf;
import lombok.Data;
import org.jeecg.modules.iot.jtt808.util.BCDUtil;
import org.jeecg.modules.iot.jtt808.vo.JT808DataPacket;

import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Data
public class LocationNewMsg  extends JT808DataPacket {

    public LocationNewMsg(ByteBuf byteBuf) {
        super(byteBuf);
    }

    private int alarm; // 告警信息 4字节
    private int statusField; // 状态 4字节
    private float latitude; // 纬度 4字节
    private float longitude; // 经度 4字节
    private short elevation; // 海拔高度 2字节
    private short speed; // 速度 2字节
    private short direction; // 方向 2字节
    private String time; // 时间 6字节BCD

    // 附加信息项
    private Integer mileage; // 里程 4字节
    private Integer oilLevel; // 油量 2字节
    private Integer recordSpeed; // 行驶记录功能获取的速度 2字节
    private Integer extendedSignalStatus; // 扩展车辆信号状态位 4字节
    private Integer ioStatus; // IO状态位 2字节
    private Integer analogQuantity; // 模拟量 4字节
    private Integer signalStrength; // 无线通信网络信号强度 1字节
    private Integer gnssCount; // GNSS卫星数量 1字节
    private Long baseStationInfo; // 基站信息 0xE1
    private Integer lockStatus; // 锁状态 0xF2
    private Long gnss4GInfo; // 4G 基站信息 0x60
    private String bluetoothBeacon; // 蓝牙信标 0xF5
    private Integer angle; // 角度上报 0xF9
    private Integer faultInfo0xE4; // 故障信息上报 0xE4
    private Integer faultInfo0xE5; // 故障信息上报 0xE5
    private Integer faultInfo0xE6; // 故障信息上报 0xE6
    private Integer mileageCurrent; // 本次里程 0xA9


    private static final Map<Integer, String> INFO_FIELD_MAP = new HashMap<>();

    static {
        INFO_FIELD_MAP.put(0x01, "mileage");
        INFO_FIELD_MAP.put(0x02, "oilLevel");
        INFO_FIELD_MAP.put(0x03, "recordSpeed");
        INFO_FIELD_MAP.put(0x25, "extendedSignalStatus");
        INFO_FIELD_MAP.put(0x2A, "ioStatus");
        INFO_FIELD_MAP.put(0x2B, "analogQuantity");
        INFO_FIELD_MAP.put(0x30, "signalStrength");
        INFO_FIELD_MAP.put(0x31, "gnssCount");
        INFO_FIELD_MAP.put(0xE1, "baseStationInfo");
        INFO_FIELD_MAP.put(0xF2, "lockStatus");
        INFO_FIELD_MAP.put(0x60, "gnss4GInfo");
        INFO_FIELD_MAP.put(0xF5, "bluetoothBeacon"); // 需要根据实际数据类型调整
        INFO_FIELD_MAP.put(0xF9, "angle");
        INFO_FIELD_MAP.put(0xE4, "faultInfo0xE4");
        INFO_FIELD_MAP.put(0xE5, "faultInfo0xE5");
        INFO_FIELD_MAP.put(0xE6, "faultInfo0xE6");
        INFO_FIELD_MAP.put(0xA9, "mileageCurrent");
    }

    @Override
    public void parseBody() {
        ByteBuf bb = this.payload;

        // 反转义处理
        ByteBuf unescapedBb =  bb;

        this.setAlarm(unescapedBb.readInt());
        this.setStatusField(unescapedBb.readInt());
        this.setLatitude(unescapedBb.readUnsignedInt() * 1.0F / 1000000);
        this.setLongitude(unescapedBb.readUnsignedInt() * 1.0F / 1000000);
        this.setElevation(unescapedBb.readShort());
        this.setSpeed(unescapedBb.readShort());
        this.setDirection(unescapedBb.readShort());
        this.setTime(BCDUtil.toBcdTimeString(readBytes(6, unescapedBb)));

        // 解析附加信息项
        while (unescapedBb.readableBytes() > 0) {
            int infoId = unescapedBb.readUnsignedByte();
            int infoLength = unescapedBb.readUnsignedByte();
            byte[] infoData = new byte[infoLength];
            unescapedBb.readBytes(infoData);

            String fieldName = INFO_FIELD_MAP.get(infoId);
            if (fieldName != null) {
                setFieldValue(fieldName, infoData, infoLength); //  传递 infoLength 参数
            }
        }
    }

    private byte[] readBytes(int length, ByteBuf bb) {
        byte[] bytes = new byte[length];
        bb.readBytes(bytes);
        return bytes;
    }

    private void setFieldValue(String fieldName, byte[] infoData, int infoLength) {
        try {
            switch (fieldName) {
                case "gnss4GInfo":
                case "baseStationInfo":
                    Method setterLong = this.getClass().getMethod("set" + capitalize(fieldName), Long.class);
                    long longValue = 0;
                    for (int i = 0; i < infoLength; i++) {
                        longValue = (longValue << 8) | (infoData[i] & 0xFF);
                    }
                    setterLong.invoke(this, longValue);
                    break;

                case "bluetoothBeacon":
                    Method setterString = this.getClass().getMethod("set" + capitalize(fieldName), String.class);
                    String strValue = new String(infoData, StandardCharsets.UTF_8); // 假设 UTF-8 编码
                    setterString.invoke(this, strValue);
                    break;

                default:
                    // 其他字段，假设都是 Integer 类型
                    Method setterInt = this.getClass().getMethod("set" + capitalize(fieldName), Integer.class);
                    int intValue;
                    switch (infoLength) {
                        case 1:
                            intValue = infoData[0] & 0xFF;
                            break;
                        case 2:
                            intValue = ((infoData[0] & 0xFF) << 8) | (infoData[1] & 0xFF);
                            break;
                        case 4:
                            intValue = ((infoData[0] & 0xFF) << 24) | ((infoData[1] & 0xFF) << 16) | ((infoData[2] & 0xFF) << 8) | (infoData[3] & 0xFF);
                            break;
                        default:
                             return; //  或者抛出异常
                    }
                    setterInt.invoke(this, intValue);
            }
        } catch (Exception e) {
             e.printStackTrace();
                }
    }

    private String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }



}
